package com.ynunicom.dc.dingdingcontractapp.controller;

import com.alibaba.fastjson.JSONObject;
import com.ynunicom.dc.dingdingcontractapp.dto.ResponseDto;
import com.ynunicom.dc.dingdingcontractapp.dto.exception.ParamNullException;
import com.ynunicom.dc.dingdingcontractapp.dto.exception.UserNotFoundException;
import com.ynunicom.dc.dingdingcontractapp.entity.requestbodyentity.*;
import com.ynunicom.dc.dingdingcontractapp.service.FlowableService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/flowable")
public class FlowableController {

    @Autowired
    RuntimeService runtimeService;

    @Autowired
    TaskService taskService;

    @Autowired
    FlowableService flowableService;

    @Resource
    RestTemplate restTemplate;

    @Value("${server.port}")
    private Integer port;


    /**
     * 测试时使用
     */
    @RequestMapping("/killAllTask")
    public void killAllTask(){
        List<Task> taskList = taskService.createTaskQuery().list();
        Set<String> processInstanceIdSet = new HashSet<>();
        for (Task task:
                taskList) {
            processInstanceIdSet.add(task.getProcessInstanceId());
        }
        for (String id:
             new ArrayList<String>(processInstanceIdSet)) {
            log.info("[{}]流程已被删除",id);
            runtimeService.deleteProcessInstance(id,"");
        }

    }

    @SneakyThrows
    @ResponseStatus(HttpStatus.ACCEPTED)
    @PostMapping("/taskCheck")
    public ResponseDto<JSONObject> taskCheck(@RequestBody @Validated FlowableTaskCheckRequestBody flowableTaskCheckRequestBody, @RequestParam("access_token")String access_token){
        TransBody<FlowableTaskCheckRequestBody> transBody = new TransBody<>(flowableTaskCheckRequestBody,access_token);
        return ResponseDto.success(flowableService.getAllAssignedTasks(transBody));
    }


    /**
     * 此处涉及文件上传，务必使用form-data格式
     * @param userId
     * @param deptId
     * @param type
     * @param money
     * @param endDate
     * @param file
     * @param access_token
     * @return
     */
    @SneakyThrows
    @ResponseStatus(HttpStatus.ACCEPTED)
    @PostMapping(value = "/processStart")
    public ResponseDto<JSONObject> processStart(String userId, String deptId, String type, String money, long endDate, String disc, String name,MultipartFile file, @RequestParam("access_token")String access_token){
        if (file.isEmpty()){
            throw new ParamNullException("文件上传失败");
        }
        if ("".equals(userId)||"".equals(deptId)||"".equals(type)||"".equals(money)||"".equals(endDate)||"".equals(disc)||"".equals(name)){
            throw new ParamNullException("参数不全");
        }
        ProcessStartRequestBody processStartRequestBody = new ProcessStartRequestBody(userId,deptId,type,Double.parseDouble(money),endDate,disc,name);
        return ResponseDto.success(flowableService.processStart(processStartRequestBody,file,access_token));
    }

    @ResponseStatus(HttpStatus.ACCEPTED)
    @GetMapping("/getFile")
    public void getFile(@RequestParam("fileName") String fileName, HttpServletResponse httpServletResponse){
        flowableService.getFile(httpServletResponse,fileName);
    }


    @ResponseStatus(HttpStatus.ACCEPTED)
    @PostMapping("/deptJudgeAndComment")
    public ResponseDto<JSONObject> deptJudgeAndComment(@RequestBody @Validated  DeptJudgeAndComment deptJudgeAndComment,@RequestParam("access_token")String access_token){

        TransBody<DeptJudgeAndComment> transBody = new TransBody<>(deptJudgeAndComment,access_token);
        return ResponseDto.success(flowableService.deptJudgeAndComment(transBody));
    }

    @ResponseStatus(HttpStatus.ACCEPTED)
    @PostMapping("/superDeptManagerJudgeAndComment")
    public ResponseDto<JSONObject> superDeptManagerJudgeAndComment(@RequestBody @Validated  ManagerJudgeAndCommentRequestBody managerJudgeAndCommentRequestBody,@RequestParam("access_token")String access_token){
        TransBody<ManagerJudgeAndCommentRequestBody> transBody = new TransBody<>(managerJudgeAndCommentRequestBody,access_token);
        return ResponseDto.success(flowableService.managerJudgeAndComment(transBody));
    }

    @ResponseStatus(HttpStatus.ACCEPTED)
    @PostMapping("/financialJudgeAndComment")
    public ResponseDto<JSONObject> financialJudgeAndComment(@RequestBody @Validated  FinancialJudgeAndCommentRequestBody financialJudgeAndCommentRequestBody,@RequestParam("access_token")String access_token){
        TransBody<FinancialJudgeAndCommentRequestBody> transBody = new TransBody<>(financialJudgeAndCommentRequestBody,access_token);
        return ResponseDto.success(flowableService.financialJudgeAndComment(transBody));
    }

    @ResponseStatus(HttpStatus.ACCEPTED)
    @PostMapping("/legalJudgeAndComment")
    public ResponseDto<JSONObject> legalJudgeAndComment(@RequestBody @Validated  LegalJudgeAndCommentRequestBody legalJudgeAndCommentRequestBody,@RequestParam("access_token")String access_token){
        TransBody<LegalJudgeAndCommentRequestBody> transBody = new TransBody<>(legalJudgeAndCommentRequestBody,access_token);
        return ResponseDto.success(flowableService.legalJudgeAndComment(transBody));
    }

    @ResponseStatus(HttpStatus.ACCEPTED)
    @PostMapping("/leaderJudgeAndComment")
    public ResponseDto<JSONObject> leaderJudgeAndComment(@RequestBody @Validated  LeaderJudgeAndCommentRequestBody leaderJudgeAndCommentRequestBody,@RequestParam("access_token")String access_token){
        TransBody<LeaderJudgeAndCommentRequestBody> transBody = new TransBody<>(leaderJudgeAndCommentRequestBody,access_token);
        return  ResponseDto.success(flowableService.leaderJudgeAndComment(transBody));
    }

    @ResponseStatus(HttpStatus.ACCEPTED)
    @PostMapping("/contractSaverJudgeAndComment")
    public ResponseDto<JSONObject> contractSaverJudgeAndComment(@RequestBody @Validated SaverJudgeAndComment saverJudgeAndComment,@RequestParam("access_token")String access_token){
        TransBody<SaverJudgeAndComment> transBody = new TransBody<>(saverJudgeAndComment,access_token);
        return ResponseDto.success(flowableService.contractSaverJudgeAndComment(transBody));
    }

    /**
     * 修改合同，此处务必使用form-data格式
     * 此处可传新文件，可不传
     * @return
     */
    @SneakyThrows
    @ResponseStatus(HttpStatus.ACCEPTED)
    @PostMapping("/recorrect")
    public ResponseDto<JSONObject> recorrect(String userId, String deptId, String type, String money, long endDate,String taskId, String disc,String name,MultipartFile file, @RequestParam("access_token")String access_token){
        RecorrectRequestBody recorrectRequestBody = new RecorrectRequestBody(userId,deptId,type,Double.parseDouble(money),endDate,taskId,disc,name);
        return ResponseDto.success(flowableService.recorrect(recorrectRequestBody,file,access_token));
    }

    /**
     * 查询自己所提的所有正在运行中的合同
     * @param userId
     * @param access_token
     * @return
     */
    @SneakyThrows
    @GetMapping("/runningContract")
    public ResponseDto<JSONObject> runningContract(@RequestParam("userId") String userId,@RequestParam("access_token")String access_token){
        TransBody<String> transBody = new TransBody<>(userId,access_token);
        return ResponseDto.success(flowableService.runningContract(transBody));

    }

    /**
     * 发起修改或者提前终止某个合同
     */
    @SneakyThrows
    @PostMapping("/alterRunningContract")
    public ResponseDto<JSONObject> alterRunningContract(@RequestBody @Validated AlterRequestBody alterRequestBody ,@RequestParam("access_token")String access_token){
        TransBody<AlterRequestBody> transBody = new TransBody<>(alterRequestBody,access_token);
        return ResponseDto.success(flowableService.alterRunningContract(transBody));
    }

    /**
     * 删除某个指定taskId的流程实例
     * @return
     */
    @SneakyThrows
    @GetMapping("/del")
    public ResponseDto del(@RequestParam("taskId") String taskId , @RequestParam("userId") String userId, @RequestParam("access_token")String access_token){
        Map<String,String> map = new HashMap<>(1);
        map.put("access_token",access_token);
        JSONObject jsonObject = restTemplate.getForObject("http://127.0.0.1:"+port+"/user/get/"+userId+"?access_token={access_token}",JSONObject.class,map);
        if (jsonObject == null || jsonObject.getJSONObject("data").getInteger("errcode")!=0){
            throw new UserNotFoundException(String.format("用户[%s]不存在或token失效",userId));
        }
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        log.info(String.format("实例[%s]被用户[%s]删除",task.getProcessInstanceId(),userId));
        runtimeService.deleteProcessInstance(task.getProcessInstanceId(),String.format("实例[%s]被用户[%s]删除",task.getProcessInstanceId(),userId));

        return ResponseDto.success("删除成功");
    }

}
